package com.my_musc_service.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.my_musc_service.dao.CommentLikeDao;
import com.my_musc_service.dao.FavoriteDao;
import com.my_musc_service.dao.SharedCommentDao;
import com.my_musc_service.dao.UserDao;
import com.my_musc_service.entity.*;
import com.my_musc_service.exception.CustomException;
import com.my_musc_service.interceptor.LoginInterceptor;
import com.my_musc_service.service.SharedCommentService;
import com.my_musc_service.utils.JudgeFlagUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * (SharedComment)表服务实现类
 *
 * @author A.Dun
 * @since 2021-08-17 14:13:47
 */
@Service("sharedCommentService")
public class SharedCommentServiceImpl extends ServiceImpl<SharedCommentDao, SharedComment> implements SharedCommentService {
    @Resource
    private SharedCommentDao sharedCommentDao;

    @Resource
    private UserDao userDao;

    @Resource
    private FavoriteDao favoriteDao;

    @Resource
    private CommentLikeDao commentLikeDao;

    //使用编程式事务
    @Resource
    private TransactionTemplate transactionTemplate;

    private Map<Integer, String> userHeaderImgMap = new ConcurrentHashMap<>();

    private Map<Integer, List<SharedComment>> parentCommentGroup = new ConcurrentHashMap<>();

    private void setUserHeaderMap() {
        List<User> users = userDao.queryAll(null);
        Map<Integer, String> collect = users.stream().collect(Collectors.toMap(User::getId, user -> {
            String headerImgUrl = user.getHeaderImgUrl();
            if (StringUtils.isNotBlank(headerImgUrl)) {
                return headerImgUrl;
            } else {
                return "";
            }
        }));
        userHeaderImgMap.putAll(collect);
    }

    /**
     * 获取当前登录用户点赞评论
     *
     * @return
     */
    public List<Integer> getCommentIdList() {
        User userInfo = LoginInterceptor.getUserInfo();
        List<Integer> commentIdList = new ArrayList<>();
        if (userInfo != null) {
            List<CommentLike> commentLikeList = commentLikeDao.selectList(new QueryWrapper<CommentLike>().eq("user_id", userInfo.getId()));
            commentIdList = commentLikeList.stream().map(CommentLike::getCommentId).collect(Collectors.toList());
        }
        return commentIdList;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public SharedComment queryById(Integer id) {
        return this.sharedCommentDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<SharedComment> queryAllByLimit(int offset, int limit) {
        return this.sharedCommentDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param sharedComment 实例对象
     * @return 实例对象
     */
    @Override
    public Boolean insert(SharedComment sharedComment) {
        int count = this.sharedCommentDao.insert(sharedComment);
        return JudgeFlagUtils.isChanged(count);
    }

    /**
     * 修改数据
     *
     * @param sharedComment 实例对象
     * @return 实例对象
     */
    @Override
    public SharedComment update(SharedComment sharedComment) {
        this.sharedCommentDao.update(sharedComment);
        return this.queryById(sharedComment.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.sharedCommentDao.deleteById(id) > 0;
    }

    @Override
    public List<SharedCommentVO> getSharedCommentVOByCommentData(SharedCommentData sharedCommentData) {

        Integer id = sharedCommentData.getId();
        Integer sharedSongId = sharedCommentData.getSharedSongId();
        Integer sharedSongListId = sharedCommentData.getSharedSongListId();
        Integer from = sharedCommentData.getFrom();
        Integer size = sharedCommentData.getSize();
        //顶级评论
        List<SharedComment> topCommentList = sharedCommentDao.queryAllBySharedCommentLimit(sharedSongListId, sharedSongId, 0, from, size);
        if (CollectionUtils.isEmpty(topCommentList)) {
            throw new CustomException("暂无评论");
        }
        QueryWrapper<SharedComment> queryWrapper = new QueryWrapper<>();
        if (id != null) {
            queryWrapper.eq("id", id);
        }
        if (sharedSongListId != null) {
            queryWrapper.eq("shared_song_list_id", sharedSongListId);
        }
        if (sharedSongId != null) {
            queryWrapper.eq("shared_song_id", sharedSongId);
        }
        queryWrapper.orderByAsc("id");
        List<SharedComment> commentAllList = baseMapper.selectList(queryWrapper);
        setUserHeaderMap();

        //顶级评论
//        List<SharedComment> topCommentList = commentAllList.stream().filter(comment -> 0 == comment.getParentId()).collect(Collectors.toList());
        //其他级评论
        List<SharedComment> nextCommentList = commentAllList.stream().filter(comment -> !"0".equals(comment.getParentId())).collect(Collectors.toList());
        setParentCommentGroup(commentAllList);

        //获取当前登录用户点赞评论
        List<Integer> commentIdList = getCommentIdList();

        List<SharedCommentVO> topChildCommentList = new ArrayList<>();
        for (SharedComment sharedComment : topCommentList) {
            SharedCommentVO sharedcommentVO = new SharedCommentVO();
            BeanUtils.copyProperties(sharedComment, sharedcommentVO);
            getRefHeaderImgUrl(userHeaderImgMap, sharedcommentVO);
            //判断顶级评论是否被当前用户点赞
            if (commentIdList.contains(sharedcommentVO.getId())) {
                sharedcommentVO.setIsCurrUserClick(true);
            }
            topChildCommentList.add(sharedcommentVO);
            //获取当前顶级评论的子级评论
            getAllChildCommentList(sharedcommentVO, parentCommentGroup);
        }
        System.out.println(JSON.toJSONString(topChildCommentList));
        return topChildCommentList;
    }

    private void setParentCommentGroup(List<SharedComment> commentAllList) {
        //k-v===>parentId-Comment
        Map<Integer, List<SharedComment>> collect = commentAllList.stream().collect(Collectors.groupingBy(SharedComment::getParentId));
        parentCommentGroup.putAll(collect);
    }

    private void getAllChildCommentList(SharedCommentVO sharedCommentVO, Map<Integer, List<SharedComment>> parentCommentGroup) {
        Integer id = sharedCommentVO.getId();
        //获取当前评论的子一级评论
        List<SharedComment> childCommentList = parentCommentGroup.get(id);
        List<Integer> commentIdList = getCommentIdList();
        if (!CollectionUtils.isEmpty(childCommentList)) {
            List<SharedCommentVO> childCommentVOList = childCommentList.stream().map(comment1 -> {
                SharedCommentVO sharedCommentVO1 = new SharedCommentVO();
                BeanUtils.copyProperties(comment1, sharedCommentVO1);

                if (commentIdList.contains(sharedCommentVO1.getId())) {
                    sharedCommentVO1.setIsCurrUserClick(true);
                }
                getRefHeaderImgUrl(userHeaderImgMap, sharedCommentVO1);
                return sharedCommentVO1;
            }).collect(Collectors.toList());
            sharedCommentVO.setChildCommentList(childCommentVOList);
            for (SharedCommentVO vo : childCommentVOList) {
                getAllChildCommentList(vo, parentCommentGroup);
            }
        }

    }

    private void getRefHeaderImgUrl(Map<Integer, String> userHeaderImgMap, SharedCommentVO sharedcommentVO) {
        String headerImgUrl = userHeaderImgMap.get(sharedcommentVO.getUserId());
        if (StringUtils.isNotBlank(headerImgUrl)) {
            sharedcommentVO.setHeaderImgUrl(headerImgUrl);
        }
    }

    /**
     * 判断当前用户是否已经点赞过当前评论
     *
     * @param commentId 评论id
     * @param userId    用户id
     * @return 是否点赞
     */
    private boolean isCurrUserAddCommentLike(Integer commentId, Integer userId) {
        //判断当前用户是否点过赞，commentlike
        LambdaQueryWrapper<CommentLike> commentLikeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        commentLikeLambdaQueryWrapper.eq(CommentLike::getCommentId, commentId);
        List<CommentLike> commentLikeList = commentLikeDao.selectList(commentLikeLambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(commentLikeList)) {
            List<Integer> currCommentListUserList = commentLikeList.stream()
                    .map(CommentLike::getUserId).collect(Collectors.toList());
            return currCommentListUserList.contains(userId);
        }
        return false;
    }


    @Override
    public Boolean addClickCount(SharedComment sharedComment) {
        List<SharedComment> sharedComments = baseMapper.queryAll(sharedComment);
        if (!CollectionUtils.isEmpty(sharedComments)) {
            SharedComment sharedCommentData = sharedComments.get(0);
            Integer clickCount = sharedCommentData.getClickCount();

            //判断当前用户是否点过赞，commentlike
            if (isCurrUserAddCommentLike(sharedCommentData.getId(), LoginInterceptor.getUserInfo().getId())) {
                throw new CustomException("当前用户已对此评论点赞");
            }

            if (clickCount != null) {
                clickCount += 1;
            } else {
                clickCount = 0;
            }
            sharedCommentData.setClickCount(clickCount);

            //修改当前用户与评论的关联信息
            CommentLike commentLike = new CommentLike();
            setCommentLike(sharedCommentData, commentLike);
            transactionTemplate.execute((status) -> {
                commentLikeDao.insert(commentLike);
                int count = baseMapper.update(sharedCommentData);
                return JudgeFlagUtils.isChanged(count);
            });
            return Boolean.TRUE;
        } else {
            throw new CustomException("更新失败");
        }
    }


    @Override
    public Boolean delClickCount(SharedComment sharedComment) {
        List<SharedComment> sharedComments = baseMapper.queryAll(sharedComment);
        if (!CollectionUtils.isEmpty(sharedComments)) {
            SharedComment sharedCommentData = sharedComments.get(0);
            Integer clickCount = sharedCommentData.getClickCount();

            //判断当前用户是否已经取消当前评论的赞，commentlike
            if (!isCurrUserAddCommentLike(sharedCommentData.getId(), LoginInterceptor.getUserInfo().getId())) {
                throw new CustomException("当前用户已取消评论点赞，无需再次取消");
            }

            if (clickCount != null) {
                clickCount -= 1;
            }
            sharedCommentData.setClickCount(clickCount);

            //修改当前用户与评论的关联信息
            CommentLike commentLike = new CommentLike();
            setCommentLike(sharedCommentData, commentLike);
            transactionTemplate.execute(transactionStatus -> {
                commentLikeDao.delete(new QueryWrapper<CommentLike>().setEntity(commentLike));
                int count = baseMapper.update(sharedCommentData);
                return JudgeFlagUtils.isChanged(count);
            });
            return Boolean.TRUE;
        } else {
            throw new CustomException("更新失败");
        }
    }

    private void setCommentLike(SharedComment sharedCommentData, CommentLike commentLike) {
        Integer sharedSongId = sharedCommentData.getSharedSongId();
        if (sharedSongId != null) {
            commentLike.setSharedSongId(sharedSongId);
        }

        Integer sharedSongListId = sharedCommentData.getSharedSongListId();
        if (sharedSongListId != null) {
            commentLike.setSharedSongListId(sharedSongListId);
        }
        commentLike.setId(null);
        commentLike.setCommentId(sharedCommentData.getId());
        commentLike.setUserId(sharedCommentData.getUserId());
    }

    @Override
    public List<SharedCommentVO> getHotCommentsBySharedCommentData(SharedCommentData sharedCommentData) {
        Integer sharedSongListId = sharedCommentData.getSharedSongListId();
        Integer sharedSongId = sharedCommentData.getSharedSongId();
        QueryWrapper<SharedComment> sharedCommentQueryWrapper = new QueryWrapper<>();
        if (sharedSongListId != null) {
            sharedCommentQueryWrapper.eq("shared_song_list_id", sharedSongListId);
        }
        if (sharedSongId != null) {
            sharedCommentQueryWrapper.eq("shared_song_id", sharedSongId);
        }

        //顶级评论中的热评
        sharedCommentQueryWrapper.eq("parent_id", 0);
        sharedCommentQueryWrapper.orderByDesc("click_count", "create_time");
        List<SharedComment> hotCommentList = baseMapper.selectList(sharedCommentQueryWrapper);
        if (CollectionUtils.isEmpty(hotCommentList)) {
            throw new CustomException("暂无评论");
        }
        List<SharedComment> commentAllList = baseMapper.selectList(null);
        //k-v===>parentId-Comment
        setParentCommentGroup(commentAllList);
        setUserHeaderMap();
        List<Integer> commentIdList = getCommentIdList();
        List<SharedCommentVO> topChildCommentList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(hotCommentList)) {
            SharedComment sharedComment1 = hotCommentList.get(0);
            SharedCommentVO sharedcommentVO = new SharedCommentVO();
            BeanUtils.copyProperties(sharedComment1, sharedcommentVO);
            getRefHeaderImgUrl(userHeaderImgMap, sharedcommentVO);
            if (commentIdList.contains(sharedcommentVO.getId())) {
                sharedcommentVO.setIsCurrUserClick(true);
            }
            topChildCommentList.add(sharedcommentVO);
            //getAllChildCommentList(sharedcommentVO, parentCommentGroup);
        }
        return topChildCommentList;
    }


    /**使用自查询来实现*/

}
